home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / srcuc.zip / DOSXCUTL.ASM < prev    next >
Assembly Source File  |  1992-05-05  |  10KB  |  370 lines

  1. ;;; -*-Midas-*-
  2. ;;;
  3. ;;;    $Header: /scheme/dos386/microcode/RCS/dosxcutl.asm,v 1.1 1992/05/05 06:55:13 jinx Exp $
  4. ;;;
  5. ;;;    Copyright (c) 1992 Massachusetts Institute of Technology
  6. ;;;
  7. ;;;    This material was developed by the Scheme project at the
  8. ;;;    Massachusetts Institute of Technology, Department of
  9. ;;;    Electrical Engineering and Computer Science.  Permission to
  10. ;;;    copy this software, to redistribute it, and to use it for any
  11. ;;;    purpose is granted, subject to the following restrictions and
  12. ;;;    understandings.
  13. ;;;
  14. ;;;    1. Any copy made of this software must include this copyright
  15. ;;;    notice in full.
  16. ;;;
  17. ;;;    2. Users of this software agree to make their best efforts (a)
  18. ;;;    to return to the MIT Scheme project any improvements or
  19. ;;;    extensions that they make, so that these may be included in
  20. ;;;    future releases; and (b) to inform MIT of noteworthy uses of
  21. ;;;    this software.
  22. ;;;
  23. ;;;    3. All materials developed as a consequence of the use of this
  24. ;;;    software shall duly acknowledge such use, in accordance with
  25. ;;;    the usual standards of acknowledging credit in academic
  26. ;;;    research.
  27. ;;;
  28. ;;;    4. MIT has made no warrantee or representation that the
  29. ;;;    operation of this software will be error-free, and MIT is
  30. ;;;    under no obligation to provide any services, by way of
  31. ;;;    maintenance, update, or otherwise.
  32. ;;;
  33. ;;;    5. In conjunction with products arising from the use of this
  34. ;;;    material, there shall be no use of the name of the
  35. ;;;    Massachusetts Institute of Technology nor of any adaptation
  36. ;;;    thereof in any advertising, promotional, or sales literature
  37. ;;;    without prior written consent from MIT in each case.
  38. ;;;
  39.  
  40. .386
  41. .model small
  42.     .code
  43.  
  44.     public _DPMI_GP_exception_method
  45. _DPMI_GP_exception_method:
  46.     cmp    40[esp],080000000h
  47.     je    DPMI_exception_method_merge
  48.     lea    esp,32[esp]        ; pop args
  49. ;    jmpf    -32[esp]        ; invoke previous handler
  50.     db    0ffh
  51.     db    06ch
  52.     db    024h
  53.     db    0e0h
  54.  
  55. DPMI_exception_method_merge:
  56.     lea    esp,8[esp]        ; pop previous handler
  57.     ;; fall through
  58.  
  59. ;;    frame on entry to DPMI_exception_method
  60. ;;    
  61. ;;28    trapped SS
  62. ;;24    trapped    ESP
  63. ;;20    trapped EFLAGS
  64. ;;16    trapped CS
  65. ;;12    trapped EIP
  66. ;;8    TRAP error code
  67. ;;4    DPMI return hook CS
  68. ;;0    DPMI return hook EIP
  69. ;; <Above this is a standard DPMI exception frame>
  70. ;;20    TRAP number
  71. ;;16    C handler DS
  72. ;;12    C handler CS    
  73. ;;8    C handler EIP
  74. ;;4    trap handling SS
  75. ;;0    trap handling ESP
  76. ;; <old ebp goes here>
  77. ;;
  78. ;; This code assumes that the trapped ESP is valid.
  79. ;; It will push from it.
  80. ;; Thus this code cannot be used for a stack fault exception.
  81.  
  82.     public _DPMI_exception_method
  83. _DPMI_exception_method:
  84.     push    ebp
  85.     mov    ebp,esp
  86.     push    es
  87.     push    eax
  88.     push    ecx
  89.     push    edx
  90.     push    ebx
  91.  
  92.     mov    eax,4[ebp+4]        ; trap frame SS
  93.     mov    ecx,0[ebp+4]        ; trap frame ESP
  94.     xor    ebx,ebx
  95.     mov    ebx,28[ebp+28]        ; trapped SS
  96.     mov    edx,24[ebp+28]        ; trapped ESP
  97.     cmp    ecx,0
  98.     jne    set_up_trap_frame
  99.     mov    ecx,edx            ; Use the trapped stack
  100.     mov    eax,ebx            ; to build the trap frame
  101.  
  102. set_up_trap_frame:
  103.     push    eax
  104.     pop    es
  105.  
  106.     sub    ecx,4            ; push trapped SS
  107.     mov    es:[ecx],ebx
  108.     
  109.     sub    ecx,4            ; push trapped ESP
  110.     mov    es:[ecx],edx
  111.     
  112.     sub    ecx,4            ; push trapped EFLAGS
  113.     mov    eax,20[ebp+28]
  114.     mov    es:[ecx],eax
  115.  
  116.     sub    ecx,4            ; push trapped CS
  117.     xor    eax,eax
  118.     mov    ax,16[ebp+28]
  119.     mov    es:[ecx],eax
  120.  
  121.     sub    ecx,4            ; push trapped EIP
  122.     mov    eax,12[ebp+28]
  123.     mov    es:[ecx],eax
  124.  
  125.     sub    ecx,4            ; push trap code
  126.     mov    eax,8[ebp+28]
  127.     mov    es:[ecx],eax
  128.  
  129.     sub    ecx,4            ; push trap number
  130.     mov    eax,20[ebp+4]
  131.     mov    es:[ecx],eax
  132.  
  133.     sub    ecx,4            ; push funcptr DS
  134.     mov    eax,16[ebp+4]
  135.     mov    es:[ecx],eax
  136.  
  137.     sub    ecx,4            ; push funcptr CS
  138.     mov    eax,12[ebp+4]
  139.     mov    es:[ecx],eax
  140.  
  141.     sub    ecx,4            ; push funcptr EIP
  142.     mov    eax,8[ebp+4]
  143.     mov    es:[ecx],eax
  144.  
  145.     mov    28[ebp+28],es        ; store hook SS
  146.     mov    24[ebp+28],ecx        ; store hook ESP
  147.  
  148.     mov    16[ebp+28],cs        ; replace trapped CS
  149.     jmp    DPMI_obtain_hook_pc
  150.  
  151. DPMI_after_obtain_hook_pc:
  152.     pop    eax            ; PC of obtain_pc
  153.     mov    12[ebp+28],eax        ; replace trapped EIP
  154.  
  155.     pop    ebx
  156.     pop    edx
  157.     pop    ecx
  158.     pop    eax
  159.     pop    es
  160.     pop    ebp
  161.         lea     esp,24[esp]        ; pop args
  162.  
  163. ;       The assembler does not assemble the following instruction correctly.
  164. ;    ret    far            ; resume thread
  165.         db      0cbh
  166.  
  167. ;;    Kludge to obtain the offset of DPMI_exception_method_hook
  168.     
  169. DPMI_obtain_hook_pc:
  170.     call    DPMI_after_obtain_hook_pc
  171.  
  172. ;;    Intercepted trap frame:
  173. ;;    
  174. ;;36    trapped SS
  175. ;;32    trapped ESP    <Typically a pointer to offset 40>
  176. ;;28    trapped EFLAGS
  177. ;;24    trapped CS
  178. ;;20    trapped EIP
  179. ;;16    trap code
  180. ;;12    trap number
  181. ;;8    C function DS
  182. ;;4    C function CS
  183. ;;0    C function EIP
  184.  
  185.     public DPMI_exception_method_hook
  186. DPMI_exception_method_hook:
  187.     push    ebp            ; preserve trapped ebp
  188.     mov    ebp,esp
  189.     push    gs            ; -4
  190.     push    fs            ; -8
  191.     push    es            ; -12
  192.     push    ds            ; -16
  193.     push    36[ebp+4]        ; -20 trapped ss
  194.     push    24[ebp+4]        ; -24 trapped cs
  195.     push    28[ebp+4]        ; -28 trapped eflags
  196.     push    20[ebp+4]        ; -32 trapped eip
  197.     push    edi            ; -36
  198.     push    esi            ; -40
  199.     push    [ebp]            ; -44 trapped ebp
  200.     push    32[ebp+4]        ; -48 trapped esp
  201.     push    ebx            ; -52
  202.     push    edx            ; -56
  203.     push    ecx            ; -60
  204.     push    eax            ; -64
  205.     push    esp            ; sigcontext ptr
  206.     push    16[ebp+4]        ; trap code
  207.     push    12[ebp+4]        ; trap number
  208.  
  209.     mov    ds,8[ebp+4]        ; DS of handler
  210.     mov    edx,4[ebp+4]        ; CS of handler
  211.     mov    eax,0[ebp+4]        ; EIP of handler
  212.     cmp    edx,0            ; test CS of handler
  213.     jne    DPMI_use_far_call
  214.     call    eax            ; Invoke handler
  215.     jmp    DPMI_continue_after_exception
  216.  
  217. DPMI_after_continuation_setup:
  218. ;;    Build far RET frame on stack
  219.  
  220.     push    edx            ; CS of handler
  221.     push    eax            ; EIP of handler
  222.  
  223. ;    ret    far            ; Invoke handler
  224.         db      0cbh
  225.  
  226. DPMI_use_far_call:
  227.     push    cs            ; Simulate a far call
  228.     call    DPMI_after_continuation_setup
  229.  
  230. DPMI_continue_after_exception:
  231. ;;
  232. ;;    If the handler returns, update machine state and `return' to
  233. ;;    the trapped code.
  234. ;;
  235.     add    esp,12            ; pop args to C handler
  236.  
  237.     mov    eax,-48[ebp]        ; update esp
  238.     mov    32[ebp+4],eax
  239.     mov    eax,-44[ebp]        ; update ebp
  240.     mov    [ebp],eax
  241.     mov    eax,-32[ebp]        ; update eip
  242.     mov    20[ebp+4],eax
  243.     mov    eax,-28[ebp]        ; update eflags
  244.     mov    28[ebp+4],eax
  245.     mov    eax,-24[ebp]        ; update cs
  246.     mov    24[ebp+4],eax
  247.     mov    eax,-20[ebp]        ; update ss
  248.     mov    36[ebp+4],eax
  249.  
  250.     pop    eax
  251.     pop    ecx
  252.     pop    edx
  253.     pop    ebx
  254.     add    esp,8            ; ignore esp and ebp
  255.     pop    esi
  256.     pop    edi
  257.     add    esp,16            ; ignore eip, eflags, cs, ss
  258.     pop    ds
  259.     pop    es
  260.     pop    fs
  261.     pop    gs
  262.  
  263. ;;    If this were part of the OS, the following instructions would
  264. ;;    do what we want, assuming that we were running at a higher
  265. ;;    privilege level than the interrupted task.  We need a
  266. ;;    `return-to-outer-level' IRETD that restores ESP and SS in
  267. ;;    addition to EIP, CS, and EFLAGS.
  268. ;;
  269. ;;    However, the architecture does not allow us to specify that
  270. ;;    explicitly, and in all likelihood an IRETD will be taken to
  271. ;;    mean a `return-to-samel-level' IRETD, which will not pop and
  272. ;;    update SS and ESP!
  273. ;;
  274. ;;    pop    ebp
  275. ;;    lea    esp,20[esp]        ; bump past trap info
  276. ;;    iretd                ; I wish
  277. ;;    
  278. ;;    The only way to correctly emulate it is to construct a piece
  279. ;;    of code that contains an explicit far jump to the return
  280. ;;    CS:EIP after loading EFLAGS, SS, and ESP from the stack.
  281. ;;    Unfortunately we can't conveniently create such a thunk here,
  282. ;;    since we don't have a pair of selectors representing a code
  283. ;;    segment and a writable data segment with the same base and
  284. ;;    limit.
  285. ;;
  286. ;;    Instead what this code will do is check whether the stack would
  287. ;;    not change (same SS and offset to immediately above the frame).
  288. ;;    If so, after moving the data around, we'll just do a far return.
  289. ;;
  290. ;;    Otherwise, we will build a far return frame on the target stack,
  291. ;;    switch stacks, and do a far return.
  292. ;;
  293. ;;    This will only work if the target stack is reasonable (and is
  294. ;;    big enough for a few words).  This is particularly not true in
  295. ;;    the case of a stack fault, but we would expect the returning
  296. ;;    handler to have changed the stack to a valid one in that case
  297. ;;    -- not a valid assumption.
  298. ;;
  299. ;;    In addition, the stack comparison assumes that different selectors
  300. ;;    mean different stacks, which is also not a valid assumption.
  301. ;;    particularly since 32-bit programs often have different SS and DS
  302. ;;    selectors mapping over the same linear range.
  303. ;;    The code also assumes that even if the selectors are the same,
  304. ;;    the target range is either identical to the default,
  305. ;;    or non-overlapping.
  306.  
  307.     push    eax            ; -4
  308.     mov    ax,ss
  309.     cmp    ax,36[ebp+4]
  310.     jne    DPMI_different_stacks
  311.     lea    eax,40[ebp+4]
  312.     cmp    eax,32[ebp+4]
  313.     jne    DPMI_different_stacks
  314.  
  315. ;;     Easy case:  The target stack is what we would return to trivially.
  316. ;;    Overwrite SS and ESP with CS and EIP, restore flags, and do a far
  317. ;;    return.
  318.  
  319.     mov    eax,24[ebp+4]        ; Move CS
  320.     mov    36[ebp+4],eax
  321.     mov    eax,20[ebp+4]        ; Move EIP
  322.     mov    32[ebp+4],eax
  323.     pop    eax
  324.     pop    ebp
  325.     lea    esp,28[ebp]        ; Pop trap info and old CS and EIP
  326.     popfd                ; Restore eflags
  327. ;
  328. ;       The assembler does not assemble the following instruction correctly.
  329. ;    ret    far            ; resume thread
  330.         db      0cbh
  331.     
  332. DPMI_different_stacks:
  333.     push    edx            ; -8  Scratch regs
  334.     push    ds            ; -12 These two must be contiguous
  335.     push    ecx            ; -16  for LDS instruction below!
  336.     mov    ds,36[ebp+4]        ; target stack SS
  337.     mov    ecx,32[ebp+4]        ; target stack ESP
  338.  
  339.     sub    ecx,4            ; push target CS
  340.     mov    eax,24[ebp+4]
  341.     mov    [ecx],eax
  342.  
  343.     sub    ecx,4            ; push target EIP
  344.     mov    eax,20[ebp+4]
  345.     mov    [ecx],eax
  346.  
  347.     sub    ecx,4            ; push target EFLAGS
  348.     mov    eax,28[ebp+4]
  349.     mov    [ecx],eax
  350. ;;
  351. ;;    Switch stacks
  352. ;;
  353.     mov    dx,ss            ; Preserve current stack
  354.     mov    ax,ds
  355.     mov    ss,ax            ; This instruction locks
  356.     mov    esp,ecx            ;  interrupts around this one!
  357.     mov    ds,dx
  358.     mov    ecx,ebp
  359.  
  360.     mov    ebp,[ecx]        ; Restore regs
  361.     mov    eax,-4[ecx]
  362.     mov    edx,-8[ecx]
  363.     lds    ecx,-16[ecx]
  364.     popfd
  365.  
  366. ;    ret    far            ; resume thread
  367.         db      0cbh
  368.  
  369. end
  370.